package org.putrpctorest.resource;

import java.beans.PropertyDescriptor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

import org.apache.cxf.common.util.SortedArraySet;

public enum CollectionType {

	LIST(List.class, ArrayList.class), SET(Set.class, HashSet.class), SORTED_SET(
			SortedSet.class, SortedArraySet.class);

	public static CollectionType fromType(Class<?> collectionType) {

		if (List.class.isAssignableFrom(collectionType)) {
			return LIST;
		} else if (Set.class.isAssignableFrom(collectionType)) {
			return SET;
		} else if (SortedSet.class.isAssignableFrom(collectionType)) {
			return SORTED_SET;
		}
		return null;
	}

	public static Class<?> getTypeFromPropertyDescriptor(
			PropertyDescriptor propertyDescriptor) {

		
		return getTypeFromTypeAndGenericType(propertyDescriptor
				.getPropertyType(), propertyDescriptor.getReadMethod()
				.getGenericReturnType());
	}
	
	public static Class<?> getTypeFromTypeAndGenericType(Class<?> type, Type genericType) {

		CollectionType collectionType = fromType(type);

		if (collectionType != null) {
			if (genericType instanceof ParameterizedType) {
				return (Class<?>) ((ParameterizedType) genericType)
						.getActualTypeArguments()[0];
			} else {
				return Object.class;
			}
		} else {
			return type;
		}
	}

	
	public static CollectionType getCollectionTypeFromPropertyDescriptor(
			PropertyDescriptor propertyDescriptor) {
		return CollectionType.fromType(propertyDescriptor.getPropertyType());
	}

	private Class<?> baseCollecionType;
	private Class<?> actualCollectionType;

	private CollectionType(Class<?> baseCollecionType,
			Class<?> actualCollectionType) {
		this.baseCollecionType = baseCollecionType;
		this.actualCollectionType = actualCollectionType;

	}

	public Class<?> getBaseCollecionType() {
		return baseCollecionType;
	}

	public Class<?> getActualCollectionType() {
		return actualCollectionType;
	}

}
